home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 1.iso / toolbox / src / exampleCode / opengl / GLUT / progs / examples / highlight.c < prev    next >
C/C++ Source or Header  |  1996-11-11  |  9KB  |  404 lines

  1.  
  2. /* Copyright (c) Mark J. Kilgard, 1994. */
  3.  
  4. /* This program is freely distributable without licensing fees 
  5.    and is provided without guarantee or warrantee expressed or 
  6.    implied. This program is -not- in the public domain. */
  7.  
  8. /**
  9.  * (c) Copyright 1993, Silicon Graphics, Inc.
  10.  * ALL RIGHTS RESERVED 
  11.  * Permission to use, copy, modify, and distribute this software for 
  12.  * any purpose and without fee is hereby granted, provided that the above
  13.  * copyright notice appear in all copies and that both the copyright notice
  14.  * and this permission notice appear in supporting documentation, and that 
  15.  * the name of Silicon Graphics, Inc. not be used in advertising
  16.  * or publicity pertaining to distribution of the software without specific,
  17.  * written prior permission. 
  18.  *
  19.  * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS"
  20.  * AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
  21.  * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
  22.  * FITNESS FOR A PARTICULAR PURPOSE.  IN NO EVENT SHALL SILICON
  23.  * GRAPHICS, INC.  BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
  24.  * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY
  25.  * KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION,
  26.  * LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF
  27.  * THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC.  HAS BEEN
  28.  * ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON
  29.  * ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE
  30.  * POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE.
  31.  * 
  32.  * US Government Users Restricted Rights 
  33.  * Use, duplication, or disclosure by the Government is subject to
  34.  * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
  35.  * (c)(1)(ii) of the Rights in Technical Data and Computer Software
  36.  * clause at DFARS 252.227-7013 and/or in similar or successor
  37.  * clauses in the FAR or the DOD or NASA FAR Supplement.
  38.  * Unpublished-- rights reserved under the copyright laws of the
  39.  * United States.  Contractor/manufacturer is Silicon Graphics,
  40.  * Inc., 2011 N.  Shoreline Blvd., Mountain View, CA 94039-7311.
  41.  *
  42.  * OpenGL(TM) is a trademark of Silicon Graphics, Inc.
  43.  */
  44. /*
  45.  *  scene.c
  46.  *  This program demonstrates the use of the GL lighting model.
  47.  *  Objects are drawn using a grey material characteristic. 
  48.  *  A single light source illuminates the objects.
  49.  */
  50. #include <stdlib.h>
  51. #include <stdarg.h>
  52. #include <stdio.h>
  53. #include <GL/glut.h>
  54.  
  55. #define BUFSIZE 512
  56.  
  57. #define TORUS        1
  58. #define TETRAHEDRON    2
  59. #define ICOSAHEDRON    3
  60.  
  61. GLuint selectBuf[BUFSIZE];
  62.  
  63. int W = 500, H = 500;
  64. GLfloat x, y;
  65. int locating = 0;
  66. int theObject = 0;
  67. int menu_inuse = 0;
  68. int mouse_state = 0;
  69.  
  70. char *objectNames[] =
  71. {"Nothing", "Torus", "Tetrahedron", "Icosahedron"};
  72.  
  73. void
  74. output(GLfloat x, GLfloat y, char *format,...)
  75. {
  76.   va_list args;
  77.   char buffer[200], *p;
  78.  
  79.   va_start(args, format);
  80.   vsprintf(buffer, format, args);
  81.   va_end(args);
  82.   glPushMatrix();
  83.   glTranslatef(x, y, 0);
  84.   for (p = buffer; *p; p++)
  85.     glutStrokeCharacter(GLUT_STROKE_ROMAN, *p);
  86.   glPopMatrix();
  87. }
  88.  
  89. /* Initialize material property and light source. */
  90. void
  91. myinit(void)
  92. {
  93.   GLfloat light_ambient[] =
  94.   {0.2, 0.2, 0.2, 1.0};
  95.   GLfloat light_diffuse[] =
  96.   {1.0, 1.0, 1.0, 1.0};
  97.   GLfloat light_specular[] =
  98.   {1.0, 1.0, 1.0, 1.0};
  99.   GLfloat light_position[] =
  100.   {1.0, 1.0, 1.0, 0.0};
  101.  
  102.   glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient);
  103.   glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse);
  104.   glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular);
  105.   glLightfv(GL_LIGHT0, GL_POSITION, light_position);
  106.  
  107.   glEnable(GL_LIGHT0);
  108.   glDepthFunc(GL_LESS);
  109.   glEnable(GL_DEPTH_TEST);
  110.   glEnable(GL_LIGHTING);
  111.  
  112.   glSelectBuffer(BUFSIZE, selectBuf);
  113.  
  114.   glNewList(TORUS, GL_COMPILE);
  115.   glutSolidTorus(0.275, 0.85, 10, 15);
  116.   glEndList();
  117.   glNewList(TETRAHEDRON, GL_COMPILE);
  118.   glutSolidTetrahedron();
  119.   glEndList();
  120.   glNewList(ICOSAHEDRON, GL_COMPILE);
  121.   glutSolidIcosahedron();
  122.   glEndList();
  123. }
  124.  
  125. void
  126. highlightBegin(void)
  127. {
  128.   static GLfloat red[4] =
  129.   {1.0, 0.0, 0.0, 1.0};
  130.  
  131.   glPushAttrib(GL_LIGHTING_BIT | GL_CURRENT_BIT);
  132.   glMaterialfv(GL_FRONT, GL_DIFFUSE, red);
  133.   glColor3f(1.0, 0.0, 0.0);
  134. }
  135.  
  136. void
  137. highlightEnd(void)
  138. {
  139.   glPopAttrib();
  140. }
  141.  
  142. void
  143. draw(void)
  144. {
  145.   glPushMatrix();
  146.   glScalef(1.3, 1.3, 1.3);
  147.   glRotatef(20.0, 1.0, 0.0, 0.0);
  148.  
  149.   glLoadName(2);
  150.   glPushMatrix();
  151.   if (theObject == 2)
  152.     highlightBegin();
  153.   glTranslatef(-0.75, -0.5, 0.0);
  154.   glRotatef(270.0, 1.0, 0.0, 0.0);
  155.   glCallList(TETRAHEDRON);
  156.   if (theObject == 2)
  157.     highlightEnd();
  158.   glPopMatrix();
  159.  
  160.   glLoadName(1);
  161.   glPushMatrix();
  162.   if (theObject == 1)
  163.     highlightBegin();
  164.   glTranslatef(-0.75, 0.5, 0.0);
  165.   glRotatef(90.0, 1.0, 0.0, 0.0);
  166.   glCallList(TORUS);
  167.   if (theObject == 1)
  168.     highlightEnd();
  169.   glPopMatrix();
  170.  
  171.   glLoadName(3);
  172.   glPushMatrix();
  173.   if (theObject == 3)
  174.     highlightBegin();
  175.   glTranslatef(0.75, 0.0, -1.0);
  176.   glCallList(ICOSAHEDRON);
  177.   if (theObject == 3)
  178.     highlightEnd();
  179.   glPopMatrix();
  180.  
  181.   glPopMatrix();
  182. }
  183.  
  184. void
  185. myortho(void)
  186. {
  187.   if (W <= H)
  188.     glOrtho(-2.5, 2.5, -2.5 * (GLfloat) H / (GLfloat) W,
  189.       2.5 * (GLfloat) H / (GLfloat) W, -10.0, 10.0);
  190.   else
  191.     glOrtho(-2.5 * (GLfloat) W / (GLfloat) H,
  192.       2.5 * (GLfloat) W / (GLfloat) H, -2.5, 2.5, -10.0, 10.0);
  193. }
  194.  
  195. /*  processHits() prints out the contents of the 
  196.  *  selection array.
  197.  */
  198. void
  199. processHits(GLint hits, GLuint buffer[])
  200. {
  201.   GLuint depth = ~0;
  202.   unsigned int i, getThisName;
  203.   GLuint names, *ptr;
  204.   GLuint newObject;
  205.  
  206.   ptr = (GLuint *) buffer;
  207.   newObject = 0;
  208.   for (i = 0; i < hits; i++) {  /* for each hit  */
  209.     getThisName = 0;
  210.     names = *ptr;
  211.     ptr++;              /* skip # name */
  212.     if (*ptr <= depth) {
  213.       depth = *ptr;
  214.       getThisName = 1;
  215.     }
  216.     ptr++;              /* skip z1 */
  217.     if (*ptr <= depth) {
  218.       depth = *ptr;
  219.       getThisName = 1;
  220.     }
  221.     ptr++;              /* skip z2 */
  222.  
  223.     if (getThisName)
  224.       newObject = *ptr;
  225.     ptr += names;       /* skip the names list */
  226.   }
  227.   if (theObject != newObject) {
  228.     theObject = newObject;
  229.     glutPostRedisplay();
  230.   }
  231. }
  232.  
  233. void
  234. locate(int value)
  235. {
  236.   GLint viewport[4];
  237.   GLint hits;
  238.  
  239.   if (locating) {
  240.     if (mouse_state == GLUT_ENTERED) {
  241.       (void) glRenderMode(GL_SELECT);
  242.       glInitNames();
  243.       glPushName(-1);
  244.  
  245.       glMatrixMode(GL_PROJECTION);
  246.       glPushMatrix();
  247.       glLoadIdentity();
  248.       viewport[0] = 0;
  249.       viewport[1] = 0;
  250.       viewport[2] = W;
  251.       viewport[3] = H;
  252.       gluPickMatrix(x, H - y, 5.0, 5.0, viewport);
  253.       myortho();
  254.       glMatrixMode(GL_MODELVIEW);
  255.       draw();
  256.       glMatrixMode(GL_PROJECTION);
  257.       glPopMatrix();
  258.       glMatrixMode(GL_MODELVIEW);
  259.       hits = glRenderMode(GL_RENDER);
  260.     } else {
  261.       hits = 0;
  262.     }
  263.     processHits(hits, selectBuf);
  264.   }
  265.   locating = 0;
  266. }
  267.  
  268. void
  269. passive(int newx, int newy)
  270. {
  271.   x = newx;
  272.   y = newy;
  273.   if (!locating) {
  274.     locating = 1;
  275.     glutTimerFunc(0, locate, 0);
  276.   }
  277. }
  278.  
  279. void
  280. entry(int state)
  281. {
  282.   mouse_state = state;
  283.   if (!menu_inuse) {
  284.     if (state == GLUT_LEFT) {
  285.       if (theObject != 0) {
  286.         theObject = 0;
  287.         glutPostRedisplay();
  288.       }
  289.     }
  290.   }
  291. }
  292.  
  293. void
  294. display(void)
  295. {
  296.   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  297.   draw();
  298.  
  299.   glPushAttrib(GL_ENABLE_BIT);
  300.   glDisable(GL_DEPTH_TEST);
  301.   glDisable(GL_LIGHTING);
  302.   glDisable(GL_LINE_SMOOTH);
  303.  
  304.   glMatrixMode(GL_PROJECTION);
  305.   glPushMatrix();
  306.   glLoadIdentity();
  307.   gluOrtho2D(0, 3000, 0, 3000);
  308.   glMatrixMode(GL_MODELVIEW);
  309.   glPushMatrix();
  310.   glLoadIdentity();
  311.   output(80, 2800, "Automatically names object under mouse.");
  312.   output(80, 100, "Located: %s.", objectNames[theObject]);
  313.   glPopMatrix();
  314.   glMatrixMode(GL_PROJECTION);
  315.   glPopMatrix();
  316.   glMatrixMode(GL_MODELVIEW);
  317.   glPopAttrib();
  318.  
  319.   glutSwapBuffers();
  320. }
  321.  
  322. void
  323. myReshape(int w, int h)
  324. {
  325.   W = w;
  326.   H = h;
  327.   glViewport(0, 0, W, H);
  328.   glMatrixMode(GL_PROJECTION);
  329.   glLoadIdentity();
  330.   myortho();
  331.   glMatrixMode(GL_MODELVIEW);
  332. }
  333.  
  334. void
  335. polygon_mode(int value)
  336. {
  337.   switch (value) {
  338.   case 1:
  339.     glEnable(GL_LIGHTING);
  340.     glDisable(GL_BLEND);
  341.     glEnable(GL_DEPTH_TEST);
  342.     glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
  343.     break;
  344.   case 2:
  345.     glDisable(GL_LIGHTING);
  346.     glColor3f(1.0, 1.0, 1.0);
  347.     glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
  348.     glEnable(GL_LINE_SMOOTH);
  349.     glEnable(GL_BLEND);
  350.     glDisable(GL_DEPTH_TEST);
  351.     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  352.     break;
  353.   }
  354.   glutPostRedisplay();
  355. }
  356.  
  357. void
  358. mstatus(int status, int newx, int newy)
  359. {
  360.   if (status == GLUT_MENU_NOT_IN_USE) {
  361.     menu_inuse = 0;
  362.     passive(newx, newy);
  363.   } else {
  364.     menu_inuse = 1;
  365.   }
  366. }
  367.  
  368. void
  369. main_menu(int value)
  370. {
  371.   if (value == 666)
  372.     exit(0);
  373. }
  374.  
  375. /*  Main Loop
  376.  *  Open window with initial window size, title bar, 
  377.  *  RGBA display mode, and handle input events.
  378.  */
  379. int
  380. main(int argc, char **argv)
  381. {
  382.   int submenu;
  383.  
  384.   glutInit(&argc, argv);
  385.   glutInitWindowSize(W, H);
  386.   glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
  387.   glutCreateWindow(argv[0]);
  388.   myinit();
  389.   glutReshapeFunc(myReshape);
  390.   glutDisplayFunc(display);
  391.   submenu = glutCreateMenu(polygon_mode);
  392.   glutAddMenuEntry("Filled", 1);
  393.   glutAddMenuEntry("Outline", 2);
  394.   glutCreateMenu(main_menu);
  395.   glutAddMenuEntry("Quit", 666);
  396.   glutAddSubMenu("Polygon mode", submenu);
  397.   glutAttachMenu(GLUT_RIGHT_BUTTON);
  398.   glutPassiveMotionFunc(passive);
  399.   glutEntryFunc(entry);
  400.   glutMenuStatusFunc(mstatus);
  401.   glutMainLoop();
  402.   return 0;             /* ANSI C requires main to return int. */
  403. }
  404.